package generator

import (
	"fmt"
	"k8s.io/apimachinery/pkg/util/validation"
	"strings"
	"v8s/compose/model"

	"v8s-controller/internal/configuration"

	corev1 "k8s.io/api/core/v1"
	resource "k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

type (
	VolumeClaimsGenerator struct {
		properties configuration.GeneratorProperties
	}
)

const (
	requestedSize      = "100Mi"
	VolumeClaimPattern = "%s-claim"
)

var (
	PersistentVolumeClaimMeta = metav1.TypeMeta{
		Kind:       "PersistentVolumeClaim",
		APIVersion: "v1",
	}
)

func NewVolumeClaimsGenerator(properties configuration.GeneratorProperties) *VolumeClaimsGenerator {
	return &VolumeClaimsGenerator{
		properties: properties,
	}
}

func (g *VolumeClaimsGenerator) Generate(volumes model.Volumes) []*corev1.PersistentVolumeClaim {
	result := make([]*corev1.PersistentVolumeClaim, 0, len(volumes))

	//TODO: remove after testing
	rw := corev1.ReadWriteMany

	for key := range volumes {
		claim := &corev1.PersistentVolumeClaim{
			TypeMeta: PersistentVolumeClaimMeta,
			ObjectMeta: metav1.ObjectMeta{
				Name: GenerateVolumeClaimName(key),
			},
			Spec: corev1.PersistentVolumeClaimSpec{
				AccessModes: []corev1.PersistentVolumeAccessMode{rw},
				Resources: corev1.ResourceRequirements{
					Requests: corev1.ResourceList{
						corev1.ResourceStorage: resource.MustParse(requestedSize),
					},
				},
				StorageClassName: &g.properties.Volumes.DefaultStorageClassName,
			},
		}

		result = append(result, claim)
	}

	return result
}

func GenerateVolumeClaimName(key model.VolumeName) string {
	name := fmt.Sprintf(VolumeClaimPattern, key)

	if len(validation.IsDNS1123Subdomain(name)) > 0 {
		name = fmt.Sprintf(VolumeClaimPattern, strings.ToLower(strings.ReplaceAll(string(key), "_", "-")))
	}

	return name
}
